package com.beerandjesus.sportofkings.handicapper.strategy.brisnet.singlefile;

import com.beerandjesus.sportofkings.handicapper.factory.ProfileFactory;
import com.beerandjesus.sportofkings.handicapper.model.HorseAnalysisResult;
import com.beerandjesus.sportofkings.handicapper.model.NonMaidenHorseAnalysisResultImpl;
import com.beerandjesus.sportofkings.handicapper.model.RaceAnalysisResultVO;
import com.beerandjesus.sportofkings.handicapper.model.RaceAnalysisResultVOImpl;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Horse;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.HorseRace;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Race;
import com.beerandjesus.sportofkings.handicapper.profile.postprocessor.ProfilesPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class NonMaidenRaceAnalysisStrategyImpl extends
        AbstractRaceAnalysisStrategy implements
        NonMaidenRaceAnalysisStrategy<HorseRace> {

    private final SpeedWinPlaceShowResolver speedWinPlaceShowResolver = new SpeedWinPlaceShowResolver();
    private final UpCloseWhenStalkingResolver upCloseWhenStalkingResolver = new UpCloseWhenStalkingResolver();
    private final ResultTypeResolver resultTypeResolver = new ResultTypeResolver();
    private final WinsOffPaceResolver winsOffPaceResolver = new WinsOffPaceResolver();

    @Autowired
    private ProfileFactory profileFactory;
    @Autowired
    private List<ProfilesPostProcessor> postProcessors;

    public RaceAnalysisResultVO analyze(HorseRace horseRace) {
        Race race = horseRace.getRace();
        List<Horse> horses = horseRace.getHorses();
        RaceAnalysisResultVOImpl vo = new RaceAnalysisResultVOImpl();
        setCommonFields(vo, race, horses);
        List<HorseAnalysisResult> results = new ArrayList<HorseAnalysisResult>();
        for (Horse horse : horses) {
            NonMaidenHorseAnalysisResultImpl result = new NonMaidenHorseAnalysisResultImpl();
            result.setPostPosition(getPostPosition(horse));

            // Horse name
            result.setName(horse.getName());

            // Morning line odds
            getMorningLineOddsResolver().resolveMorningLineOdds(result, horse);

            // Result type
            resultTypeResolver.resolveTypeForNonMaidens(result, horse);

            // Speed & wps
            speedWinPlaceShowResolver.resolveSpeedAndWPS(result, race, horse);

            // Workouts
            getFastWorkoutsResolver().resolveFastWorkouts(result, horse);

            switch (result.getResultType()) {
                case SLOW_EARLY_SPEED:
                    upCloseWhenStalkingResolver.resolveUpCloseWhenStalking(result, horse);
                    break;
                case FAST_EARLY_SPEED:
                    winsOffPaceResolver.resolveWinsOffPace(result, horse);
                    break;
            }

            // Profiles
            result.setProfiles(getProfileFactory().getProfiles(horseRace, horse));

            // Key trainer statistics
            result.setKeyTrainerStatistics(getKeyTrainerStatisticsResolver().resolve(horse));

            results.add(result);
        }
        for (ProfilesPostProcessor postProcessor : getPostProcessors()) {
            postProcessor.postProcessProfiles(results);
        }

        vo.setResults(results);
        return vo;
    }

    public ProfileFactory getProfileFactory() {
        return profileFactory;
    }

    public void setProfileFactory(ProfileFactory profileFactory) {
        this.profileFactory = profileFactory;
    }

    public List<ProfilesPostProcessor> getPostProcessors() {
        return postProcessors;
    }

    public void setPostProcessors(List<ProfilesPostProcessor> postProcessors) {
        this.postProcessors = postProcessors;
    }

}
